<?php

namespace App\Http\Controllers\Api;

use App\Http\Requests\Api\PlanRequest;
use App\Http\Resources\PlanCollectionResource;
use App\Http\Resources\PlanResource;
use App\Models\Plan;
use App\Models\User;
use Illuminate\Auth\Access\AuthorizationException;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;

class PlanController extends Controller
{
    /**
     * 获取拍摄界面需要的基础信息
     * @return mixed
     */
    public function params()
    {
        $user = $this->user();

        if ($user->isAdmin()) {
            $users = User::where('status', 1)
                ->where('id', '<>', $this->id())
                ->pluck('name', 'id');
        } else {
            $users = $user->customs()->where('status', 1)->pluck('name', 'id');
        }
        $canAdd = $user->can('plans.store');
        $canQuery = $user->can('plans.index');

        return $this->success(compact('users', 'canAdd', 'canQuery'));
    }

    /**
     * 拍摄列表
     * @param Request $request
     * @return mixed
     */
    public function index(Request $request)
    {
        $params = $request->all();

        if ($this->user()->isAdmin()) {
            $query = Plan::query();
        } else {
            $query = $this->user()->plans();
        }

        $plans = $query->with('users')->when($params['status'] ?? [], function ($query, $status) {
            if (!is_array($status)) {
                $status = [$status];
            }
            $query->whereIn('status', $status);
        })->when($params['name'] ?? '', function ($query, $title) {
            $query->where('title', 'like', '%' . $title . '%');
        })->orderBy('id', 'desc')->paginate($params['size'] ?? 9);

        return $this->success(new PlanCollectionResource($plans));
    }

    /**
     * 新增拍摄
     * @param PlanRequest $request
     * @return mixed
     */
    public function store(PlanRequest $request)
    {
        try {
            DB::beginTransaction();
            $data = $request->only(['title', 'cover', 'status', 'description', 'date', 'address']);
            $plan = $this->user()->owns()->create(array_filter($data));
            $this->syncUsers($plan, $request);

            DB::commit();
            return $this->success(new PlanResource($plan));
        } catch (\Exception $exception) {
            DB::rollBack();
            return $this->failed($exception->getMessage());
        }
    }

    /**
     * 拍摄详情
     * @param Plan $plan
     * @return mixed
     * @throws AuthorizationException
     */
    public function show(Plan $plan)
    {
        $plan = Plan::with(['photoes', 'users' => function (BelongsToMany $query) use ($plan) {
            $query->where('users.id', '<>', $plan->user_id);
        }])->find($plan->id);

        $this->authorize('view', $plan); // 用户资源授权策略

        if (empty($plan)) {
            return $this->failed('找不到该拍摄详情', 404);
        }

        return $this->success(new PlanResource($plan));
    }

    /**
     * 更新拍摄
     * @param PlanRequest $request
     * @param Plan $plan
     * @return mixed
     * @throws AuthorizationException
     */
    public function update(PlanRequest $request, Plan $plan)
    {
        $this->authorize('update', $plan); // 用户资源授权策略

        try {
            DB::beginTransaction();

            $data = $request->only(['title', 'cover', 'status', 'description', 'date', 'address']);
            $plan->fill(array_filter($data));
            $plan->save();
            $this->syncUsers($plan, $request);

            DB::commit();
            return $this->success(new PlanResource($plan));
        } catch (\Exception $exception) {
            DB::rollBack();
            return $this->failed($exception->getMessage());
        }
    }

    /**
     * 更新关联关系
     * @param Plan $plan
     * @param Request $request
     * @return void
     */
    protected function syncUsers(Plan $plan, Request $request)
    {
        $userIds = is_array($request->uids) && !empty($request->uids) ? array_merge($request->uids, [$this->id()]) : [$this->id()];
        $userIds = User::whereIn('id', $userIds)->pluck('id')->toArray();
        $plan->users()->sync($userIds);
    }

    /**
     * 删除拍摄
     * @param Plan $plan
     * @return mixed
     * @throws AuthorizationException
     */
    public function destroy(Plan $plan)
    {
        $this->authorize('update', $plan); // 用户资源授权策略

        try {
            DB::beginTransaction();
            $plan->photoes()->delete();
            $plan->delete();
            DB::commit();
            return $this->success('拍摄删除成功');
        } catch (\Exception $exception) {
            DB::rollBack();
            return $this->failed($exception->getMessage());
        }
    }
}
